define("ace/snippets", ["require", "exports", "module", "ace/lib/dom", "ace/lib/oop", "ace/lib/event_emitter", "ace/lib/lang", "ace/range", "ace/range_list", "ace/keyboard/hash_handler", "ace/tokenizer", "ace/clipboard", "ace/editor"], function (e, t, n) {
    "use strict";

    function p(e) {
        var t = (new Date).toLocaleString("en-us", e);
        return t.length == 1 ? "0" + t : t
    }

    var r = e("./lib/dom"), i = e("./lib/oop"), s = e("./lib/event_emitter").EventEmitter, o = e("./lib/lang"),
        u = e("./range").Range, a = e("./range_list").RangeList, f = e("./keyboard/hash_handler").HashHandler,
        l = e("./tokenizer").Tokenizer, c = e("./clipboard"), h = {
            CURRENT_WORD: function (e) {
                return e.session.getTextRange(e.session.getWordRange())
            },
            SELECTION: function (e, t, n) {
                var r = e.session.getTextRange();
                return n ? r.replace(/\n\r?([ \t]*\S)/g, "\n" + n + "$1") : r
            },
            CURRENT_LINE: function (e) {
                return e.session.getLine(e.getCursorPosition().row)
            },
            PREV_LINE: function (e) {
                return e.session.getLine(e.getCursorPosition().row - 1)
            },
            LINE_INDEX: function (e) {
                return e.getCursorPosition().row
            },
            LINE_NUMBER: function (e) {
                return e.getCursorPosition().row + 1
            },
            SOFT_TABS: function (e) {
                return e.session.getUseSoftTabs() ? "YES" : "NO"
            },
            TAB_SIZE: function (e) {
                return e.session.getTabSize()
            },
            CLIPBOARD: function (e) {
                return c.getText && c.getText()
            },
            FILENAME: function (e) {
                return /[^/\\]*$/.exec(this.FILEPATH(e))[0]
            },
            FILENAME_BASE: function (e) {
                return /[^/\\]*$/.exec(this.FILEPATH(e))[0].replace(/\.[^.]*$/, "")
            },
            DIRECTORY: function (e) {
                return this.FILEPATH(e).replace(/[^/\\]*$/, "")
            },
            FILEPATH: function (e) {
                return "/not implemented.txt"
            },
            WORKSPACE_NAME: function () {
                return "Unknown"
            },
            FULLNAME: function () {
                return "Unknown"
            },
            BLOCK_COMMENT_START: function (e) {
                var t = e.session.$mode || {};
                return t.blockComment && t.blockComment.start || ""
            },
            BLOCK_COMMENT_END: function (e) {
                var t = e.session.$mode || {};
                return t.blockComment && t.blockComment.end || ""
            },
            LINE_COMMENT: function (e) {
                var t = e.session.$mode || {};
                return t.lineCommentStart || ""
            },
            CURRENT_YEAR: p.bind(null, {year: "numeric"}),
            CURRENT_YEAR_SHORT: p.bind(null, {year: "2-digit"}),
            CURRENT_MONTH: p.bind(null, {month: "numeric"}),
            CURRENT_MONTH_NAME: p.bind(null, {month: "long"}),
            CURRENT_MONTH_NAME_SHORT: p.bind(null, {month: "short"}),
            CURRENT_DATE: p.bind(null, {day: "2-digit"}),
            CURRENT_DAY_NAME: p.bind(null, {weekday: "long"}),
            CURRENT_DAY_NAME_SHORT: p.bind(null, {weekday: "short"}),
            CURRENT_HOUR: p.bind(null, {hour: "2-digit", hour12: !1}),
            CURRENT_MINUTE: p.bind(null, {minute: "2-digit"}),
            CURRENT_SECOND: p.bind(null, {second: "2-digit"})
        };
    h.SELECTED_TEXT = h.SELECTION;
    var d = function () {
        this.snippetMap = {}, this.snippetNameMap = {}
    };
    (function () {
        i.implement(this, s), this.getTokenizer = function () {
            return d.$tokenizer || this.createTokenizer()
        }, this.createTokenizer = function () {
            function e(e) {
                return e = e.substr(1), /^\d+$/.test(e) ? [{tabstopId: parseInt(e, 10)}] : [{text: e}]
            }

            function t(e) {
                return "(?:[^\\\\" + e + "]|\\\\.)"
            }

            var n = {
                regex: "/(" + t("/") + "+)/", onMatch: function (e, t, n) {
                    var r = n[0];
                    return r.fmtString = !0, r.guard = e.slice(1, -1), r.flag = "", ""
                }, next: "formatString"
            };
            return d.$tokenizer = new l({
                start: [{
                    regex: /\\./, onMatch: function (e, t, n) {
                        var r = e[1];
                        return r == "}" && n.length ? e = r : "`$\\".indexOf(r) != -1 && (e = r), [e]
                    }
                }, {
                    regex: /}/, onMatch: function (e, t, n) {
                        return [n.length ? n.shift() : e]
                    }
                }, {regex: /\$(?:\d+|\w+)/, onMatch: e}, {
                    regex: /\$\{[\dA-Z_a-z]+/, onMatch: function (t, n, r) {
                        var i = e(t.substr(1));
                        return r.unshift(i[0]), i
                    }, next: "snippetVar"
                }, {regex: /\n/, token: "newline", merge: !1}],
                snippetVar: [{
                    regex: "\\|" + t("\\|") + "*\\|", onMatch: function (e, t, n) {
                        var r = e.slice(1, -1).replace(/\\[,|\\]|,/g, function (e) {
                            return e.length == 2 ? e[1] : "\0"
                        }).split("\0").map(function (e) {
                            return {value: e}
                        });
                        return n[0].choices = r, [r[0]]
                    }, next: "start"
                }, n, {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "start"}],
                formatString: [{
                    regex: /:/, onMatch: function (e, t, n) {
                        return n.length && n[0].expectElse ? (n[0].expectElse = !1, n[0].ifEnd = {elseEnd: n[0]}, [n[0].ifEnd]) : ":"
                    }
                }, {
                    regex: /\\./, onMatch: function (e, t, n) {
                        var r = e[1];
                        return r == "}" && n.length ? e = r : "`$\\".indexOf(r) != -1 ? e = r : r == "n" ? e = "\n" : r == "t" ? e = "	" : "ulULE".indexOf(r) != -1 && (e = {
                            changeCase: r,
                            local: r > "a"
                        }), [e]
                    }
                }, {
                    regex: "/\\w*}", onMatch: function (e, t, n) {
                        var r = n.shift();
                        return r && (r.flag = e.slice(1, -1)), this.next = r && r.tabstopId ? "start" : "", [r || e]
                    }, next: "start"
                }, {
                    regex: /\$(?:\d+|\w+)/, onMatch: function (e, t, n) {
                        return [{text: e.slice(1)}]
                    }
                }, {
                    regex: /\${\w+/, onMatch: function (e, t, n) {
                        var r = {text: e.slice(2)};
                        return n.unshift(r), [r]
                    }, next: "formatStringVar"
                }, {regex: /\n/, token: "newline", merge: !1}, {
                    regex: /}/, onMatch: function (e, t, n) {
                        var r = n.shift();
                        return this.next = r && r.tabstopId ? "start" : "", [r || e]
                    }, next: "start"
                }],
                formatStringVar: [{
                    regex: /:\/\w+}/, onMatch: function (e, t, n) {
                        var r = n[0];
                        return r.formatFunction = e.slice(2, -1), [n.shift()]
                    }, next: "formatString"
                }, n, {
                    regex: /:[\?\-+]?/, onMatch: function (e, t, n) {
                        e[1] == "+" && (n[0].ifEnd = n[0]), e[1] == "?" && (n[0].expectElse = !0)
                    }, next: "formatString"
                }, {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "formatString"}]
            }), d.$tokenizer
        }, this.tokenizeTmSnippet = function (e, t) {
            return this.getTokenizer().getLineTokens(e, t).tokens.map(function (e) {
                return e.value || e
            })
        }, this.getVariableValue = function (e, t, n) {
            if (/^\d+$/.test(t)) return (this.variables.__ || {})[t] || "";
            if (/^[A-Z]\d+$/.test(t)) return (this.variables[t[0] + "__"] || {})[t.substr(1)] || "";
            t = t.replace(/^TM_/, "");
            if (!this.variables.hasOwnProperty(t)) return "";
            var r = this.variables[t];
            return typeof r == "function" && (r = this.variables[t](e, t, n)), r == null ? "" : r
        }, this.variables = h, this.tmStrFormat = function (e, t, n) {
            if (!t.fmt) return e;
            var r = t.flag || "", i = t.guard;
            i = new RegExp(i, r.replace(/[^gim]/g, ""));
            var s = typeof t.fmt == "string" ? this.tokenizeTmSnippet(t.fmt, "formatString") : t.fmt, o = this,
                u = e.replace(i, function () {
                    var e = o.variables.__;
                    o.variables.__ = [].slice.call(arguments);
                    var t = o.resolveVariables(s, n), r = "E";
                    for (var i = 0; i < t.length; i++) {
                        var u = t[i];
                        if (typeof u == "object") {
                            t[i] = "";
                            if (u.changeCase && u.local) {
                                var a = t[i + 1];
                                a && typeof a == "string" && (u.changeCase == "u" ? t[i] = a[0].toUpperCase() : t[i] = a[0].toLowerCase(), t[i + 1] = a.substr(1))
                            } else u.changeCase && (r = u.changeCase)
                        } else r == "U" ? t[i] = u.toUpperCase() : r == "L" && (t[i] = u.toLowerCase())
                    }
                    return o.variables.__ = e, t.join("")
                });
            return u
        }, this.tmFormatFunction = function (e, t, n) {
            return t.formatFunction == "upcase" ? e.toUpperCase() : t.formatFunction == "downcase" ? e.toLowerCase() : e
        }, this.resolveVariables = function (e, t) {
            function f(t) {
                var n = e.indexOf(t, s + 1);
                n != -1 && (s = n)
            }

            var n = [], r = "", i = !0;
            for (var s = 0; s < e.length; s++) {
                var o = e[s];
                if (typeof o == "string") {
                    n.push(o), o == "\n" ? (i = !0, r = "") : i && (r = /^\t*/.exec(o)[0], i = /\S/.test(o));
                    continue
                }
                if (!o) continue;
                i = !1;
                if (o.fmtString) {
                    var u = e.indexOf(o, s + 1);
                    u == -1 && (u = e.length), o.fmt = e.slice(s + 1, u), s = u
                }
                if (o.text) {
                    var a = this.getVariableValue(t, o.text, r) + "";
                    o.fmtString && (a = this.tmStrFormat(a, o, t)), o.formatFunction && (a = this.tmFormatFunction(a, o, t)), a && !o.ifEnd ? (n.push(a), f(o)) : !a && o.ifEnd && f(o.ifEnd)
                } else o.elseEnd ? f(o.elseEnd) : o.tabstopId != null ? n.push(o) : o.changeCase != null && n.push(o)
            }
            return n
        };
        var e = function (e, t, n) {
            function l(e) {
                var t = [];
                for (var n = 0; n < e.length; n++) {
                    var r = e[n];
                    if (typeof r == "object") {
                        if (f[r.tabstopId]) continue;
                        var i = e.lastIndexOf(r, n - 1);
                        r = t[i] || {tabstopId: r.tabstopId}
                    }
                    t[n] = r
                }
                return t
            }

            n === void 0 && (n = {});
            var r = e.getCursorPosition(), i = e.session.getLine(r.row), s = e.session.getTabString(),
                o = i.match(/^\s*/)[0];
            r.column < o.length && (o = o.slice(0, r.column)), t = t.replace(/\r/g, "");
            var u = this.tokenizeTmSnippet(t);
            u = this.resolveVariables(u, e), u = u.map(function (e) {
                return e == "\n" && !n.excludeExtraIndent ? e + o : typeof e == "string" ? e.replace(/\t/g, s) : e
            });
            var a = [];
            u.forEach(function (e, t) {
                if (typeof e != "object") return;
                var n = e.tabstopId, r = a[n];
                r || (r = a[n] = [], r.index = n, r.value = "", r.parents = {});
                if (r.indexOf(e) !== -1) return;
                e.choices && !r.choices && (r.choices = e.choices), r.push(e);
                var i = u.indexOf(e, t + 1);
                if (i === -1) return;
                var s = u.slice(t + 1, i), o = s.some(function (e) {
                    return typeof e == "object"
                });
                o && !r.value ? r.value = s : s.length && (!r.value || typeof r.value != "string") && (r.value = s.join(""))
            }), a.forEach(function (e) {
                e.length = 0
            });
            var f = {};
            for (var c = 0; c < u.length; c++) {
                var h = u[c];
                if (typeof h != "object") continue;
                var p = h.tabstopId, d = a[p], v = u.indexOf(h, c + 1);
                if (f[p]) {
                    f[p] === h && (delete f[p], Object.keys(f).forEach(function (e) {
                        d.parents[e] = !0
                    }));
                    continue
                }
                f[p] = h;
                var m = d.value;
                typeof m != "string" ? m = l(m) : h.fmt && (m = this.tmStrFormat(m, h, e)), u.splice.apply(u, [c + 1, Math.max(0, v - c)].concat(m, h)), d.indexOf(h) === -1 && d.push(h)
            }
            var g = 0, y = 0, b = "";
            return u.forEach(function (e) {
                if (typeof e == "string") {
                    var t = e.split("\n");
                    t.length > 1 ? (y = t[t.length - 1].length, g += t.length - 1) : y += e.length, b += e
                } else e && (e.start ? e.end = {row: g, column: y} : e.start = {row: g, column: y})
            }), {text: b, tabstops: a, tokens: u}
        };
        this.getDisplayTextForSnippet = function (t, n) {
            var r = e.call(this, t, n);
            return r.text
        }, this.insertSnippetForSelection = function (t, n, r) {
            r === void 0 && (r = {});
            var i = e.call(this, t, n, r), s = t.getSelectionRange();
            r.range && r.range.compareRange(s) === 0 && (s = r.range);
            var o = t.session.replace(s, i.text), u = new v(t), a = t.inVirtualSelectionMode && t.selection.index;
            u.addTabstops(i.tabstops, s.start, o, a)
        }, this.insertSnippet = function (e, t, n) {
            n === void 0 && (n = {});
            var r = this;
            n.range && !(n.range instanceof u) && (n.range = u.fromPoints(n.range.start, n.range.end));
            if (e.inVirtualSelectionMode) return r.insertSnippetForSelection(e, t, n);
            e.forEachSelection(function () {
                r.insertSnippetForSelection(e, t, n)
            }, null, {keepOrder: !0}), e.tabstopManager && e.tabstopManager.tabNext()
        }, this.$getScope = function (e) {
            var t = e.session.$mode.$id || "";
            t = t.split("/").pop();
            if (t === "html" || t === "php") {
                t === "php" && !e.session.$mode.inlinePhp && (t = "html");
                var n = e.getCursorPosition(), r = e.session.getState(n.row);
                typeof r == "object" && (r = r[0]), r.substring && (r.substring(0, 3) == "js-" ? t = "javascript" : r.substring(0, 4) == "css-" ? t = "css" : r.substring(0, 4) == "php-" && (t = "php"))
            }
            return t
        }, this.getActiveScopes = function (e) {
            var t = this.$getScope(e), n = [t], r = this.snippetMap;
            return r[t] && r[t].includeScopes && n.push.apply(n, r[t].includeScopes), n.push("_"), n
        }, this.expandWithTab = function (e, t) {
            var n = this, r = e.forEachSelection(function () {
                return n.expandSnippetForSelection(e, t)
            }, null, {keepOrder: !0});
            return r && e.tabstopManager && e.tabstopManager.tabNext(), r
        }, this.expandSnippetForSelection = function (e, t) {
            var n = e.getCursorPosition(), r = e.session.getLine(n.row), i = r.substring(0, n.column),
                s = r.substr(n.column), o = this.snippetMap, u;
            return this.getActiveScopes(e).some(function (e) {
                var t = o[e];
                return t && (u = this.findMatchingSnippet(t, i, s)), !!u
            }, this), u ? t && t.dryRun ? !0 : (e.session.doc.removeInLine(n.row, n.column - u.replaceBefore.length, n.column + u.replaceAfter.length), this.variables.M__ = u.matchBefore, this.variables.T__ = u.matchAfter, this.insertSnippetForSelection(e, u.content), this.variables.M__ = this.variables.T__ = null, !0) : !1
        }, this.findMatchingSnippet = function (e, t, n) {
            for (var r = e.length; r--;) {
                var i = e[r];
                if (i.startRe && !i.startRe.test(t)) continue;
                if (i.endRe && !i.endRe.test(n)) continue;
                if (!i.startRe && !i.endRe) continue;
                return i.matchBefore = i.startRe ? i.startRe.exec(t) : [""], i.matchAfter = i.endRe ? i.endRe.exec(n) : [""], i.replaceBefore = i.triggerRe ? i.triggerRe.exec(t)[0] : "", i.replaceAfter = i.endTriggerRe ? i.endTriggerRe.exec(n)[0] : "", i
            }
        }, this.snippetMap = {}, this.snippetNameMap = {}, this.register = function (e, t) {
            function s(e) {
                return e && !/^\^?\(.*\)\$?$|^\\b$/.test(e) && (e = "(?:" + e + ")"), e || ""
            }

            function u(e, t, n) {
                return e = s(e), t = s(t), n ? (e = t + e, e && e[e.length - 1] != "$" && (e += "$")) : (e += t, e && e[0] != "^" && (e = "^" + e)), new RegExp(e)
            }

            function a(e) {
                e.scope || (e.scope = t || "_"), t = e.scope, n[t] || (n[t] = [], r[t] = {});
                var s = r[t];
                if (e.name) {
                    var a = s[e.name];
                    a && i.unregister(a), s[e.name] = e
                }
                n[t].push(e), e.prefix && (e.tabTrigger = e.prefix), !e.content && e.body && (e.content = Array.isArray(e.body) ? e.body.join("\n") : e.body), e.tabTrigger && !e.trigger && (!e.guard && /^\w/.test(e.tabTrigger) && (e.guard = "\\b"), e.trigger = o.escapeRegExp(e.tabTrigger));
                if (!e.trigger && !e.guard && !e.endTrigger && !e.endGuard) return;
                e.startRe = u(e.trigger, e.guard, !0), e.triggerRe = new RegExp(e.trigger), e.endRe = u(e.endTrigger, e.endGuard, !0), e.endTriggerRe = new RegExp(e.endTrigger)
            }

            var n = this.snippetMap, r = this.snippetNameMap, i = this;
            e || (e = []), Array.isArray(e) ? e.forEach(a) : Object.keys(e).forEach(function (t) {
                a(e[t])
            }), this._signal("registerSnippets", {scope: t})
        }, this.unregister = function (e, t) {
            function i(e) {
                var i = r[e.scope || t];
                if (i && i[e.name]) {
                    delete i[e.name];
                    var s = n[e.scope || t], o = s && s.indexOf(e);
                    o >= 0 && s.splice(o, 1)
                }
            }

            var n = this.snippetMap, r = this.snippetNameMap;
            e.content ? i(e) : Array.isArray(e) && e.forEach(i)
        }, this.parseSnippetFile = function (e) {
            e = e.replace(/\r/g, "");
            var t = [], n = {}, r = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm, i;
            while (i = r.exec(e)) {
                if (i[1]) try {
                    n = JSON.parse(i[1]), t.push(n)
                } catch (s) {
                }
                if (i[4]) n.content = i[4].replace(/^\t/gm, ""), t.push(n), n = {}; else {
                    var o = i[2], u = i[3];
                    if (o == "regex") {
                        var a = /\/((?:[^\/\\]|\\.)*)|$/g;
                        n.guard = a.exec(u)[1], n.trigger = a.exec(u)[1], n.endTrigger = a.exec(u)[1], n.endGuard = a.exec(u)[1]
                    } else o == "snippet" ? (n.tabTrigger = u.match(/^\S*/)[0], n.name || (n.name = u)) : o && (n[o] = u)
                }
            }
            return t
        }, this.getSnippetByName = function (e, t) {
            var n = this.snippetNameMap, r;
            return this.getActiveScopes(t).some(function (t) {
                var i = n[t];
                return i && (r = i[e]), !!r
            }, this), r
        }
    }).call(d.prototype);
    var v = function (e) {
        if (e.tabstopManager) return e.tabstopManager;
        e.tabstopManager = this, this.$onChange = this.onChange.bind(this), this.$onChangeSelection = o.delayedCall(this.onChangeSelection.bind(this)).schedule, this.$onChangeSession = this.onChangeSession.bind(this), this.$onAfterExec = this.onAfterExec.bind(this), this.attach(e)
    };
    (function () {
        this.attach = function (e) {
            this.index = 0, this.ranges = [], this.tabstops = [], this.$openTabstops = null, this.selectedTabstop = null, this.editor = e, this.editor.on("change", this.$onChange), this.editor.on("changeSelection", this.$onChangeSelection), this.editor.on("changeSession", this.$onChangeSession), this.editor.commands.on("afterExec", this.$onAfterExec), this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)
        }, this.detach = function () {
            this.tabstops.forEach(this.removeTabstopMarkers, this), this.ranges = null, this.tabstops = null, this.selectedTabstop = null, this.editor.removeListener("change", this.$onChange), this.editor.removeListener("changeSelection", this.$onChangeSelection), this.editor.removeListener("changeSession", this.$onChangeSession), this.editor.commands.removeListener("afterExec", this.$onAfterExec), this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler), this.editor.tabstopManager = null, this.editor = null
        }, this.onChange = function (e) {
            var t = e.action[0] == "r", n = this.selectedTabstop || {}, r = n.parents || {},
                i = (this.tabstops || []).slice();
            for (var s = 0; s < i.length; s++) {
                var o = i[s], u = o == n || r[o.index];
                o.rangeList.$bias = u ? 0 : 1;
                if (e.action == "remove" && o !== n) {
                    var a = o.parents && o.parents[n.index], f = o.rangeList.pointIndex(e.start, a);
                    f = f < 0 ? -f - 1 : f + 1;
                    var l = o.rangeList.pointIndex(e.end, a);
                    l = l < 0 ? -l - 1 : l - 1;
                    var c = o.rangeList.ranges.slice(f, l);
                    for (var h = 0; h < c.length; h++) this.removeRange(c[h])
                }
                o.rangeList.$onChange(e)
            }
            var p = this.editor.session;
            !this.$inChange && t && p.getLength() == 1 && !p.getValue() && this.detach()
        }, this.updateLinkedFields = function () {
            var e = this.selectedTabstop;
            if (!e || !e.hasLinkedRanges || !e.firstNonLinked) return;
            this.$inChange = !0;
            var n = this.editor.session, r = n.getTextRange(e.firstNonLinked);
            for (var i = 0; i < e.length; i++) {
                var s = e[i];
                if (!s.linked) continue;
                var o = s.original, u = t.snippetManager.tmStrFormat(r, o, this.editor);
                n.replace(s, u)
            }
            this.$inChange = !1
        }, this.onAfterExec = function (e) {
            e.command && !e.command.readOnly && this.updateLinkedFields()
        }, this.onChangeSelection = function () {
            if (!this.editor) return;
            var e = this.editor.selection.lead, t = this.editor.selection.anchor, n = this.editor.selection.isEmpty();
            for (var r = 0; r < this.ranges.length; r++) {
                if (this.ranges[r].linked) continue;
                var i = this.ranges[r].contains(e.row, e.column), s = n || this.ranges[r].contains(t.row, t.column);
                if (i && s) return
            }
            this.detach()
        }, this.onChangeSession = function () {
            this.detach()
        }, this.tabNext = function (e) {
            var t = this.tabstops.length, n = this.index + (e || 1);
            n = Math.min(Math.max(n, 1), t), n == t && (n = 0), this.selectTabstop(n), n === 0 && this.detach()
        }, this.selectTabstop = function (e) {
            this.$openTabstops = null;
            var t = this.tabstops[this.index];
            t && this.addTabstopMarkers(t), this.index = e, t = this.tabstops[this.index];
            if (!t || !t.length) return;
            this.selectedTabstop = t;
            var n = t.firstNonLinked || t;
            t.choices && (n.cursor = n.start);
            if (!this.editor.inVirtualSelectionMode) {
                var r = this.editor.multiSelect;
                r.toSingleRange(n);
                for (var i = 0; i < t.length; i++) {
                    if (t.hasLinkedRanges && t[i].linked) continue;
                    r.addRange(t[i].clone(), !0)
                }
            } else this.editor.selection.fromOrientedRange(n);
            this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler), this.selectedTabstop && this.selectedTabstop.choices && this.editor.execCommand("startAutocomplete", {matches: this.selectedTabstop.choices})
        }, this.addTabstops = function (e, t, n) {
            var r = this.useLink || !this.editor.getOption("enableMultiselect");
            this.$openTabstops || (this.$openTabstops = []);
            if (!e[0]) {
                var i = u.fromPoints(n, n);
                g(i.start, t), g(i.end, t), e[0] = [i], e[0].index = 0
            }
            var s = this.index, o = [s + 1, 0], f = this.ranges;
            e.forEach(function (e, n) {
                var i = this.$openTabstops[n] || e;
                for (var s = 0; s < e.length; s++) {
                    var l = e[s], c = u.fromPoints(l.start, l.end || l.start);
                    m(c.start, t), m(c.end, t), c.original = l, c.tabstop = i, f.push(c), i != e ? i.unshift(c) : i[s] = c, l.fmtString || i.firstNonLinked && r ? (c.linked = !0, i.hasLinkedRanges = !0) : i.firstNonLinked || (i.firstNonLinked = c)
                }
                i.firstNonLinked || (i.hasLinkedRanges = !1), i === e && (o.push(i), this.$openTabstops[n] = i), this.addTabstopMarkers(i), i.rangeList = i.rangeList || new a, i.rangeList.$bias = 0, i.rangeList.addList(i)
            }, this), o.length > 2 && (this.tabstops.length && o.push(o.splice(2, 1)[0]), this.tabstops.splice.apply(this.tabstops, o))
        }, this.addTabstopMarkers = function (e) {
            var t = this.editor.session;
            e.forEach(function (e) {
                e.markerId || (e.markerId = t.addMarker(e, "ace_snippet-marker", "text"))
            })
        }, this.removeTabstopMarkers = function (e) {
            var t = this.editor.session;
            e.forEach(function (e) {
                t.removeMarker(e.markerId), e.markerId = null
            })
        }, this.removeRange = function (e) {
            var t = e.tabstop.indexOf(e);
            t != -1 && e.tabstop.splice(t, 1), t = this.ranges.indexOf(e), t != -1 && this.ranges.splice(t, 1), t = e.tabstop.rangeList.ranges.indexOf(e), t != -1 && e.tabstop.splice(t, 1), this.editor.session.removeMarker(e.markerId), e.tabstop.length || (t = this.tabstops.indexOf(e.tabstop), t != -1 && this.tabstops.splice(t, 1), this.tabstops.length || this.detach())
        }, this.keyboardHandler = new f, this.keyboardHandler.bindKeys({
            Tab: function (e) {
                if (t.snippetManager && t.snippetManager.expandWithTab(e)) return;
                e.tabstopManager.tabNext(1), e.renderer.scrollCursorIntoView()
            }, "Shift-Tab": function (e) {
                e.tabstopManager.tabNext(-1), e.renderer.scrollCursorIntoView()
            }, Esc: function (e) {
                e.tabstopManager.detach()
            }
        })
    }).call(v.prototype);
    var m = function (e, t) {
        e.row == 0 && (e.column += t.column), e.row += t.row
    }, g = function (e, t) {
        e.row == t.row && (e.column -= t.column), e.row -= t.row
    };
    r.importCssString("\n.ace_snippet-marker {\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    background: rgba(194, 193, 208, 0.09);\n    border: 1px dotted rgba(211, 208, 235, 0.62);\n    position: absolute;\n}", "snippets.css", !1), t.snippetManager = new d;
    var y = e("./editor").Editor;
    (function () {
        this.insertSnippet = function (e, n) {
            return t.snippetManager.insertSnippet(this, e, n)
        }, this.expandSnippet = function (e) {
            return t.snippetManager.expandWithTab(this, e)
        }
    }).call(y.prototype)
}), define("ace/autocomplete/popup", ["require", "exports", "module", "ace/virtual_renderer", "ace/editor", "ace/range", "ace/lib/event", "ace/lib/lang", "ace/lib/dom", "ace/config"], function (e, t, n) {
    "use strict";
    var r = e("../virtual_renderer").VirtualRenderer, i = e("../editor").Editor, s = e("../range").Range,
        o = e("../lib/event"), u = e("../lib/lang"), a = e("../lib/dom"), f = e("../config").nls, l = function (e) {
            return "suggest-aria-id:".concat(e)
        }, c = function (e) {
            var t = new r(e);
            t.$maxLines = 4;
            var n = new i(t);
            return n.setHighlightActiveLine(!1), n.setShowPrintMargin(!1), n.renderer.setShowGutter(!1), n.renderer.setHighlightGutterLine(!1), n.$mouseHandler.$focusTimeout = 0, n.$highlightTagPending = !0, n
        }, h = function () {
            function e(e) {
                var t = a.createElement("div"), n = new c(t);
                e && e.appendChild(t), t.style.display = "none", n.renderer.content.style.cursor = "default", n.renderer.setStyle("ace_autocomplete"), n.renderer.container.setAttribute("role", "listbox"), n.renderer.container.setAttribute("aria-label", f("Autocomplete suggestions")), n.setOption("displayIndentGuides", !1), n.setOption("dragDelay", 150);
                var r = function () {
                };
                n.focus = r, n.$isFocused = !0, n.renderer.$cursorLayer.restartTimer = r, n.renderer.$cursorLayer.element.style.opacity = 0, n.renderer.$maxLines = 8, n.renderer.$keepTextAreaAtCursor = !1, n.setHighlightActiveLine(!1), n.session.highlight(""), n.session.$searchHighlight.clazz = "ace_highlight-marker", n.on("mousedown", function (e) {
                    var t = e.getDocumentPosition();
                    n.selection.moveToPosition(t), p.start.row = p.end.row = t.row, e.stop()
                });
                var i, h = new s(-1, 0, -1, Infinity), p = new s(-1, 0, -1, Infinity);
                p.id = n.session.addMarker(p, "ace_active-line", "fullLine"), n.setSelectOnHover = function (e) {
                    e ? h.id && (n.session.removeMarker(h.id), h.id = null) : h.id = n.session.addMarker(h, "ace_line-hover", "fullLine")
                }, n.setSelectOnHover(!1), n.on("mousemove", function (e) {
                    if (!i) {
                        i = e;
                        return
                    }
                    if (i.x == e.x && i.y == e.y) return;
                    i = e, i.scrollTop = n.renderer.scrollTop;
                    var t = i.getDocumentPosition().row;
                    h.start.row != t && (h.id || n.setRow(t), v(t))
                }), n.renderer.on("beforeRender", function () {
                    if (i && h.start.row != -1) {
                        i.$pos = null;
                        var e = i.getDocumentPosition().row;
                        h.id || n.setRow(e), v(e, !0)
                    }
                }), n.renderer.on("afterRender", function () {
                    var e = n.getRow(), t = n.renderer.$textLayer, r = t.element.childNodes[e - t.config.firstRow],
                        i = document.activeElement;
                    r !== t.selectedNode && t.selectedNode && (a.removeCssClass(t.selectedNode, "ace_selected"), i.removeAttribute("aria-activedescendant"), t.selectedNode.removeAttribute("id")), t.selectedNode = r;
                    if (r) {
                        a.addCssClass(r, "ace_selected");
                        var s = l(e);
                        r.id = s, n.renderer.container.setAttribute("aria-activedescendant", s), i.setAttribute("aria-activedescendant", s), r.setAttribute("role", "option"), r.setAttribute("aria-label", n.getData(e).value), r.setAttribute("aria-setsize", n.data.length), r.setAttribute("aria-posinset", e)
                    }
                });
                var d = function () {
                    v(-1)
                }, v = function (e, t) {
                    e !== h.start.row && (h.start.row = h.end.row = e, t || n.session._emit("changeBackMarker"), n._emit("changeHoverMarker"))
                };
                n.getHoveredRow = function () {
                    return h.start.row
                }, o.addListener(n.container, "mouseout", d), n.on("hide", d), n.on("changeSelection", d), n.session.doc.getLength = function () {
                    return n.data.length
                }, n.session.doc.getLine = function (e) {
                    var t = n.data[e];
                    return typeof t == "string" ? t : t && t.value || ""
                };
                var m = n.session.bgTokenizer;
                return m.$tokenizeRow = function (e) {
                    function s(e, n) {
                        e && r.push({type: (t.className || "") + (n || ""), value: e})
                    }

                    var t = n.data[e], r = [];
                    if (!t) return r;
                    typeof t == "string" && (t = {value: t});
                    var i = t.caption || t.value || t.name, o = i.toLowerCase(), u = (n.filterText || "").toLowerCase(),
                        a = 0, f = 0;
                    for (var l = 0; l <= u.length; l++) if (l != f && (t.matchMask & 1 << l || l == u.length)) {
                        var c = u.slice(f, l);
                        f = l;
                        var h = o.indexOf(c, a);
                        if (h == -1) continue;
                        s(i.slice(a, h), ""), a = h + c.length, s(i.slice(h, a), "completion-highlight")
                    }
                    return s(i.slice(a, i.length), ""), r.push({
                        type: "completion-spacer",
                        value: " "
                    }), t.meta && r.push({
                        type: "completion-meta",
                        value: t.meta
                    }), t.message && r.push({type: "completion-message", value: t.message}), r
                }, m.$updateOnChange = r, m.start = r, n.session.$computeWidth = function () {
                    return this.screenWidth = 0
                }, n.isOpen = !1, n.isTopdown = !1, n.autoSelect = !0, n.filterText = "", n.data = [], n.setData = function (e, t) {
                    n.filterText = t || "", n.setValue(u.stringRepeat("\n", e.length), -1), n.data = e || [], n.setRow(0)
                }, n.getData = function (e) {
                    return n.data[e]
                }, n.getRow = function () {
                    return p.start.row
                }, n.setRow = function (e) {
                    e = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length - 1, e)), p.start.row != e && (n.selection.clearSelection(), p.start.row = p.end.row = e || 0, n.session._emit("changeBackMarker"), n.moveCursorTo(e || 0, 0), n.isOpen && n._signal("select"))
                }, n.on("changeSelection", function () {
                    n.isOpen && n.setRow(n.selection.lead.row), n.renderer.scrollCursorIntoView()
                }), n.hide = function () {
                    this.container.style.display = "none", n.anchorPos = null, n.anchor = null, n.isOpen && (n.isOpen = !1, this._signal("hide"))
                }, n.tryShow = function (e, t, r, s) {
                    if (!s && n.isOpen && n.anchorPos && n.anchor && n.anchorPos.top === e.top && n.anchorPos.left === e.left && n.anchor === r) return !0;
                    var o = this.container, u = window.innerHeight, a = window.innerWidth, f = this.renderer,
                        l = f.$maxLines * t * 1.4, c = {top: 0, bottom: 0, left: 0},
                        h = u - e.top - 3 * this.$borderSize - t, p = e.top - 3 * this.$borderSize;
                    r || (p <= h || h >= l ? r = "bottom" : r = "top"), r === "top" ? (c.bottom = e.top - this.$borderSize, c.top = c.bottom - l) : r === "bottom" && (c.top = e.top + t + this.$borderSize, c.bottom = c.top + l);
                    var d = c.top >= 0 && c.bottom <= u;
                    if (!s && !d) return !1;
                    d ? f.$maxPixelHeight = null : r === "top" ? f.$maxPixelHeight = p : f.$maxPixelHeight = h, r === "top" ? (o.style.top = "", o.style.bottom = u - c.bottom + "px", n.isTopdown = !1) : (o.style.top = c.top + "px", o.style.bottom = "", n.isTopdown = !0), o.style.display = "";
                    var v = e.left;
                    return v + o.offsetWidth > a && (v = a - o.offsetWidth), o.style.left = v + "px", o.style.right = "", n.isOpen || (n.isOpen = !0, this._signal("show"), i = null), n.anchorPos = e, n.anchor = r, !0
                }, n.show = function (e, t, n) {
                    this.tryShow(e, t, n ? "bottom" : undefined, !0)
                }, n.goTo = function (e) {
                    var t = this.getRow(), n = this.session.getLength() - 1;
                    switch (e) {
                        case"up":
                            t = t <= 0 ? n : t - 1;
                            break;
                        case"down":
                            t = t >= n ? -1 : t + 1;
                            break;
                        case"start":
                            t = 0;
                            break;
                        case"end":
                            t = n
                    }
                    this.setRow(t)
                }, n.getTextLeftOffset = function () {
                    return this.$borderSize + this.renderer.$padding + this.$imageSize
                }, n.$imageSize = 0, n.$borderSize = 1, n
            }

            return e
        }();
    a.importCssString("\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n    background-color: #CAD6FA;\n    z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n    background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n    border: 1px solid #abbffe;\n    margin-top: -1px;\n    background: rgba(233,233,253,0.4);\n    position: absolute;\n    z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n    border: 1px solid rgba(109, 150, 13, 0.8);\n    background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n    opacity: 0.5;\n    margin: 0 0.9em;\n}\n.ace_completion-message {\n    color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n    color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n    color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n    width: 300px;\n    z-index: 200000;\n    border: 1px lightgray solid;\n    position: fixed;\n    box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n    line-height: 1.4;\n    background: #fefefe;\n    color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n    border: 1px #484747 solid;\n    box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n    line-height: 1.4;\n    background: #25282c;\n    color: #c1c1c1;\n}\n.ace_autocomplete_right .ace_text-layer  {\n    width: calc(100% - 8px);\n}\n.ace_autocomplete_right .ace_line {\n    display: flex;\n}\n.ace_autocomplete_right .ace_completion-spacer {\n    flex: 1;\n}\n", "autocompletion.css", !1), t.AcePopup = h, t.$singleLineEditor = c, t.getAriaId = l
}), define("ace/autocomplete/inline", ["require", "exports", "module", "ace/snippets"], function (e, t, n) {
    "use strict";
    var r = e("../snippets").snippetManager, i = function () {
        function e() {
            this.editor = null
        }

        return e.prototype.show = function (e, t, n) {
            n = n || "", e && this.editor && this.editor !== e && (this.hide(), this.editor = null);
            if (!e || !t) return !1;
            var i = t.snippet ? r.getDisplayTextForSnippet(e, t.snippet) : t.value;
            return !i || !i.startsWith(n) ? !1 : (this.editor = e, i = i.slice(n.length), i === "" ? e.removeGhostText() : e.setGhostText(i), !0)
        }, e.prototype.isOpen = function () {
            return this.editor ? !!this.editor.renderer.$ghostText : !1
        }, e.prototype.hide = function () {
            return this.editor ? (this.editor.removeGhostText(), !0) : !1
        }, e.prototype.destroy = function () {
            this.hide(), this.editor = null
        }, e
    }();
    t.AceInline = i
}), define("ace/autocomplete/util", ["require", "exports", "module"], function (e, t, n) {
    "use strict";
    t.parForEach = function (e, t, n) {
        var r = 0, i = e.length;
        i === 0 && n();
        for (var s = 0; s < i; s++) t(e[s], function (e, t) {
            r++, r === i && n(e, t)
        })
    };
    var r = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
    t.retrievePrecedingIdentifier = function (e, t, n) {
        n = n || r;
        var i = [];
        for (var s = t - 1; s >= 0; s--) {
            if (!n.test(e[s])) break;
            i.push(e[s])
        }
        return i.reverse().join("")
    }, t.retrieveFollowingIdentifier = function (e, t, n) {
        n = n || r;
        var i = [];
        for (var s = t; s < e.length; s++) {
            if (!n.test(e[s])) break;
            i.push(e[s])
        }
        return i
    }, t.getCompletionPrefix = function (e) {
        var t = e.getCursorPosition(), n = e.session.getLine(t.row), r;
        return e.completers.forEach(function (e) {
            e.identifierRegexps && e.identifierRegexps.forEach(function (e) {
                !r && e && (r = this.retrievePrecedingIdentifier(n, t.column, e))
            }.bind(this))
        }.bind(this)), r || this.retrievePrecedingIdentifier(n, t.column)
    }, t.triggerAutocomplete = function (e) {
        var t = e.getCursorPosition(), n = e.session.getLine(t.row), r = t.column === 0 ? 0 : t.column - 1, i = n[r];
        return e.completers.some(function (e) {
            if (e.triggerCharacters && Array.isArray(e.triggerCharacters)) return e.triggerCharacters.includes(i)
        })
    }
}), define("ace/autocomplete", ["require", "exports", "module", "ace/keyboard/hash_handler", "ace/autocomplete/popup", "ace/autocomplete/inline", "ace/autocomplete/popup", "ace/autocomplete/util", "ace/lib/lang", "ace/lib/dom", "ace/snippets", "ace/config"], function (e, t, n) {
    "use strict";
    var r = e("./keyboard/hash_handler").HashHandler, i = e("./autocomplete/popup").AcePopup,
        s = e("./autocomplete/inline").AceInline, o = e("./autocomplete/popup").getAriaId, u = e("./autocomplete/util"),
        a = e("./lib/lang"), f = e("./lib/dom"), l = e("./snippets").snippetManager, c = e("./config"),
        h = function (e, t) {
            t.completer && t.completer.destroy()
        }, p = function () {
            function e() {
                this.autoInsert = !1, this.autoSelect = !0, this.autoShown = !1, this.exactMatch = !1, this.inlineEnabled = !1, this.keyboardHandler = new r, this.keyboardHandler.bindKeys(this.commands), this.parentNode = null, this.blurListener = this.blurListener.bind(this), this.changeListener = this.changeListener.bind(this), this.mousedownListener = this.mousedownListener.bind(this), this.mousewheelListener = this.mousewheelListener.bind(this), this.changeTimer = a.delayedCall(function () {
                    this.updateCompletions(!0)
                }.bind(this)), this.tooltipTimer = a.delayedCall(this.updateDocTooltip.bind(this), 50)
            }

            return e.prototype.$init = function () {
                return this.popup = new i(this.parentNode || document.body || document.documentElement), this.popup.on("click", function (e) {
                    this.insertMatch(), e.stop()
                }.bind(this)), this.popup.focus = this.editor.focus.bind(this.editor), this.popup.on("show", this.$onPopupChange.bind(this)), this.popup.on("hide", this.$onHidePopup.bind(this)), this.popup.on("select", this.$onPopupChange.bind(this)), this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null)), this.popup
            }, e.prototype.$initInline = function () {
                if (!this.inlineEnabled || this.inlineRenderer) return;
                return this.inlineRenderer = new s, this.inlineRenderer
            }, e.prototype.getPopup = function () {
                return this.popup || this.$init()
            }, e.prototype.$onHidePopup = function () {
                this.inlineRenderer && this.inlineRenderer.hide(), this.hideDocTooltip()
            }, e.prototype.$onPopupChange = function (e) {
                if (this.inlineRenderer && this.inlineEnabled) {
                    var t = e ? null : this.popup.getData(this.popup.getRow()), n = u.getCompletionPrefix(this.editor);
                    this.inlineRenderer.show(this.editor, t, n) || this.inlineRenderer.hide(), this.$updatePopupPosition()
                }
                this.tooltipTimer.call(null, null)
            }, e.prototype.$updatePopupPosition = function () {
                var e = this.editor, t = e.renderer, n = t.layerConfig.lineHeight,
                    r = t.$cursorLayer.getPixelPosition(this.base, !0);
                r.left -= this.popup.getTextLeftOffset();
                var i = e.container.getBoundingClientRect();
                r.top += i.top - t.layerConfig.offset, r.left += i.left - e.renderer.scrollLeft, r.left += t.gutterWidth;
                var s = {top: r.top, left: r.left};
                t.$ghostText && t.$ghostTextWidget && this.base.row === t.$ghostText.position.row && (s.top += t.$ghostTextWidget.el.offsetHeight);
                if (this.popup.tryShow(s, n, "bottom")) return;
                if (this.popup.tryShow(r, n, "top")) return;
                this.popup.show(r, n)
            }, e.prototype.openPopup = function (e, t, n) {
                this.popup || this.$init(), this.inlineEnabled && !this.inlineRenderer && this.$initInline(), this.popup.autoSelect = this.autoSelect, this.popup.setData(this.completions.filtered, this.completions.filterText), this.editor.textInput.setAriaOptions && this.editor.textInput.setAriaOptions({
                    activeDescendant: o(this.popup.getRow()),
                    inline: this.inlineEnabled
                }), e.keyBinding.addKeyboardHandler(this.keyboardHandler), this.popup.setRow(this.autoSelect ? 0 : -1), n ? n && !t && this.detach() : (this.popup.setTheme(e.getTheme()), this.popup.setFontSize(e.getFontSize()), this.$updatePopupPosition(), this.tooltipNode && this.updateDocTooltip()), this.changeTimer.cancel()
            }, e.prototype.detach = function () {
                this.editor && (this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler), this.editor.off("changeSelection", this.changeListener), this.editor.off("blur", this.blurListener), this.editor.off("mousedown", this.mousedownListener), this.editor.off("mousewheel", this.mousewheelListener)), this.changeTimer.cancel(), this.hideDocTooltip(), this.completionProvider && this.completionProvider.detach(), this.popup && this.popup.isOpen && this.popup.hide(), this.base && this.base.detach(), this.activated = !1, this.completionProvider = this.completions = this.base = null
            }, e.prototype.changeListener = function (e) {
                var t = this.editor.selection.lead;
                (t.row != this.base.row || t.column < this.base.column) && this.detach(), this.activated ? this.changeTimer.schedule() : this.detach()
            }, e.prototype.blurListener = function (e) {
                var t = document.activeElement, n = this.editor.textInput.getElement(),
                    r = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget),
                    i = this.popup && this.popup.container;
                t != n && t.parentNode != i && !r && t != this.tooltipNode && e.relatedTarget != n && this.detach()
            }, e.prototype.mousedownListener = function (e) {
                this.detach()
            }, e.prototype.mousewheelListener = function (e) {
                this.detach()
            }, e.prototype.goTo = function (e) {
                this.popup.goTo(e)
            }, e.prototype.insertMatch = function (e, t) {
                e || (e = this.popup.getData(this.popup.getRow()));
                if (!e) return !1;
                if (e.value === "") return this.detach();
                var n = this.completions, r = this.getCompletionProvider().insertMatch(this.editor, e, n.filterText, t);
                return this.completions == n && this.detach(), r
            }, e.prototype.showPopup = function (e, t) {
                this.editor && this.detach(), this.activated = !0, this.editor = e, e.completer != this && (e.completer && e.completer.detach(), e.completer = this), e.on("changeSelection", this.changeListener), e.on("blur", this.blurListener), e.on("mousedown", this.mousedownListener), e.on("mousewheel", this.mousewheelListener), this.updateCompletions(!1, t)
            }, e.prototype.getCompletionProvider = function () {
                return this.completionProvider || (this.completionProvider = new d), this.completionProvider
            }, e.prototype.gatherCompletions = function (e, t) {
                return this.getCompletionProvider().gatherCompletions(e, t)
            }, e.prototype.updateCompletions = function (e, t) {
                if (e && this.base && this.completions) {
                    var n = this.editor.getCursorPosition(),
                        r = this.editor.session.getTextRange({start: this.base, end: n});
                    if (r == this.completions.filterText) return;
                    this.completions.setFilter(r);
                    if (!this.completions.filtered.length) return this.detach();
                    if (this.completions.filtered.length == 1 && this.completions.filtered[0].value == r && !this.completions.filtered[0].snippet) return this.detach();
                    this.openPopup(this.editor, r, e);
                    return
                }
                if (t && t.matches) {
                    var n = this.editor.getSelectionRange().start;
                    return this.base = this.editor.session.doc.createAnchor(n.row, n.column), this.base.$insertRight = !0, this.completions = new v(t.matches), this.openPopup(this.editor, "", e)
                }
                var i = this.editor.getSession(), n = this.editor.getCursorPosition(),
                    r = u.getCompletionPrefix(this.editor);
                this.base = i.doc.createAnchor(n.row, n.column - r.length), this.base.$insertRight = !0;
                var s = {exactMatch: this.exactMatch};
                this.getCompletionProvider().provideCompletions(this.editor, s, function (t, n, r) {
                    var i = n.filtered, s = u.getCompletionPrefix(this.editor);
                    if (r) {
                        if (!i.length) {
                            var o = !this.autoShown && this.emptyMessage;
                            typeof o == "function" && (o = this.emptyMessage(s));
                            if (o) {
                                var a = [{caption: this.emptyMessage(s), value: ""}];
                                this.completions = new v(a), this.openPopup(this.editor, s, e);
                                return
                            }
                            return this.detach()
                        }
                        if (i.length == 1 && i[0].value == s && !i[0].snippet) return this.detach();
                        if (this.autoInsert && !this.autoShown && i.length == 1) return this.insertMatch(i[0])
                    }
                    this.completions = n, this.openPopup(this.editor, s, e)
                }.bind(this))
            }, e.prototype.cancelContextMenu = function () {
                this.editor.$mouseHandler.cancelContextMenu()
            }, e.prototype.updateDocTooltip = function () {
                var e = this.popup, t = e.data, n = t && (t[e.getHoveredRow()] || t[e.getRow()]), r = null;
                if (!n || !this.editor || !this.popup.isOpen) return this.hideDocTooltip();
                var i = this.editor.completers.length;
                for (var s = 0; s < i; s++) {
                    var o = this.editor.completers[s];
                    if (o.getDocTooltip && n.completerId === o.id) {
                        r = o.getDocTooltip(n);
                        break
                    }
                }
                !r && typeof n != "string" && (r = n), typeof r == "string" && (r = {docText: r});
                if (!r || !r.docHTML && !r.docText) return this.hideDocTooltip();
                this.showDocTooltip(r)
            }, e.prototype.showDocTooltip = function (e) {
                this.tooltipNode || (this.tooltipNode = f.createElement("div"), this.tooltipNode.style.margin = 0, this.tooltipNode.style.pointerEvents = "auto", this.tooltipNode.tabIndex = -1, this.tooltipNode.onblur = this.blurListener.bind(this), this.tooltipNode.onclick = this.onTooltipClick.bind(this));
                var t = this.editor.renderer.theme;
                this.tooltipNode.className = "ace_tooltip ace_doc-tooltip " + (t.isDark ? "ace_dark " : "") + (t.cssClass || "");
                var n = this.tooltipNode;
                e.docHTML ? n.innerHTML = e.docHTML : e.docText && (n.textContent = e.docText), n.parentNode || this.popup.container.appendChild(this.tooltipNode);
                var r = this.popup, i = r.container.getBoundingClientRect();
                n.style.top = r.container.style.top, n.style.bottom = r.container.style.bottom, n.style.display = "block", window.innerWidth - i.right < 320 ? i.left < 320 ? r.isTopdown ? (n.style.top = i.bottom + "px", n.style.left = i.left + "px", n.style.right = "", n.style.bottom = "") : (n.style.top = r.container.offsetTop - n.offsetHeight + "px", n.style.left = i.left + "px", n.style.right = "", n.style.bottom = "") : (n.style.right = window.innerWidth - i.left + "px", n.style.left = "") : (n.style.left = i.right + 1 + "px", n.style.right = "")
            }, e.prototype.hideDocTooltip = function () {
                this.tooltipTimer.cancel();
                if (!this.tooltipNode) return;
                var e = this.tooltipNode;
                !this.editor.isFocused() && document.activeElement == e && this.editor.focus(), this.tooltipNode = null, e.parentNode && e.parentNode.removeChild(e)
            }, e.prototype.onTooltipClick = function (e) {
                var t = e.target;
                while (t && t != this.tooltipNode) {
                    if (t.nodeName == "A" && t.href) {
                        t.rel = "noreferrer", t.target = "_blank";
                        break
                    }
                    t = t.parentNode
                }
            }, e.prototype.destroy = function () {
                this.detach();
                if (this.popup) {
                    this.popup.destroy();
                    var e = this.popup.container;
                    e && e.parentNode && e.parentNode.removeChild(e)
                }
                this.editor && this.editor.completer == this && (this.editor.off("destroy", h), this.editor.completer = null), this.inlineRenderer = this.popup = this.editor = null
            }, e
        }();
    p.prototype.commands = {
        Up: function (e) {
            e.completer.goTo("up")
        }, Down: function (e) {
            e.completer.goTo("down")
        }, "Ctrl-Up|Ctrl-Home": function (e) {
            e.completer.goTo("start")
        }, "Ctrl-Down|Ctrl-End": function (e) {
            e.completer.goTo("end")
        }, Esc: function (e) {
            e.completer.detach()
        }, Return: function (e) {
            return e.completer.insertMatch()
        }, "Shift-Return": function (e) {
            e.completer.insertMatch(null, {deleteSuffix: !0})
        }, Tab: function (e) {
            var t = e.completer.insertMatch();
            if (!!t || !!e.tabstopManager) return t;
            e.completer.goTo("down")
        }, PageUp: function (e) {
            e.completer.popup.gotoPageUp()
        }, PageDown: function (e) {
            e.completer.popup.gotoPageDown()
        }
    }, p.for = function (e) {
        return e.completer instanceof p ? e.completer : (e.completer && (e.completer.destroy(), e.completer = null), c.get("sharedPopups") ? (p.$sharedInstance || (p.$sharedInstance = new p), e.completer = p.$sharedInstance) : (e.completer = new p, e.once("destroy", h)), e.completer)
    }, p.startCommand = {
        name: "startAutocomplete", exec: function (e, t) {
            var n = p.for(e);
            n.autoInsert = !1, n.autoSelect = !0, n.autoShown = !1, n.showPopup(e, t), n.cancelContextMenu()
        }, bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
    };
    var d = function () {
        function e() {
            this.active = !0
        }

        return e.prototype.insertByIndex = function (e, t, n) {
            return !this.completions || !this.completions.filtered ? !1 : this.insertMatch(e, this.completions.filtered[t], n)
        }, e.prototype.insertMatch = function (e, t, n) {
            if (!t) return !1;
            e.startOperation({command: {name: "insertMatch"}});
            if (t.completer && t.completer.insertMatch) t.completer.insertMatch(e, t); else {
                if (!this.completions) return !1;
                if (this.completions.filterText) {
                    var r;
                    e.selection.getAllRanges ? r = e.selection.getAllRanges() : r = [e.getSelectionRange()];
                    for (var i = 0, s; s = r[i]; i++) s.start.column -= this.completions.filterText.length, e.session.remove(s)
                }
                t.snippet ? l.insertSnippet(e, t.snippet, {range: t.range}) : this.$insertString(e, t), t.command && t.command === "startAutocomplete" && e.execCommand(t.command)
            }
            return e.endOperation(), !0
        }, e.prototype.$insertString = function (e, t) {
            var n = t.value || t;
            if (t.range) {
                if (e.inVirtualSelectionMode) return e.session.replace(t.range, n);
                e.forEachSelection(function () {
                    var r = e.getSelectionRange();
                    t.range.compareRange(r) === 0 ? e.session.replace(t.range, n) : e.insert(n)
                }, null, {keepOrder: !0})
            } else e.execCommand("insertstring", n)
        }, e.prototype.gatherCompletions = function (e, t) {
            var n = e.getSession(), r = e.getCursorPosition(), i = u.getCompletionPrefix(e), s = [],
                o = e.completers.length;
            return e.completers.forEach(function (a, f) {
                a.getCompletions(e, n, r, i, function (n, r) {
                    !n && r && (s = s.concat(r)), t(null, {
                        prefix: u.getCompletionPrefix(e),
                        matches: s,
                        finished: --o === 0
                    })
                })
            }), !0
        }, e.prototype.provideCompletions = function (e, t, n) {
            var r = function (e) {
                var r = e.prefix, i = e.matches;
                this.completions = new v(i), t.exactMatch && (this.completions.exactMatch = !0), t.ignoreCaption && (this.completions.ignoreCaption = !0), this.completions.setFilter(r), (e.finished || this.completions.filtered.length) && n(null, this.completions, e.finished)
            }.bind(this), i = !0, s = null;
            this.gatherCompletions(e, function (e, t) {
                if (!this.active) return;
                e && (n(e, [], !0), this.detach());
                var o = t.prefix;
                if (o.indexOf(t.prefix) !== 0) return;
                if (i) {
                    s = t;
                    return
                }
                r(t)
            }.bind(this)), i = !1;
            if (s) {
                var o = s;
                s = null, r(o)
            }
        }, e.prototype.detach = function () {
            this.active = !1
        }, e
    }(), v = function () {
        function e(e, t) {
            this.all = e, this.filtered = e, this.filterText = t || "", this.exactMatch = !1, this.ignoreCaption = !1
        }

        return e.prototype.setFilter = function (e) {
            if (e.length > this.filterText && e.lastIndexOf(this.filterText, 0) === 0) var t = this.filtered; else var t = this.all;
            this.filterText = e, t = this.filterCompletions(t, this.filterText), t = t.sort(function (e, t) {
                return t.exactMatch - e.exactMatch || t.$score - e.$score || (e.caption || e.value).localeCompare(t.caption || t.value)
            });
            var n = null;
            t = t.filter(function (e) {
                var t = e.snippet || e.caption || e.value;
                return t === n ? !1 : (n = t, !0)
            }), this.filtered = t
        }, e.prototype.filterCompletions = function (e, t) {
            var n = [], r = t.toUpperCase(), i = t.toLowerCase();
            e:for (var s = 0, o; o = e[s]; s++) {
                var u = !this.ignoreCaption && o.caption || o.value || o.snippet;
                if (!u) continue;
                var a = -1, f = 0, l = 0, c, h;
                if (this.exactMatch) {
                    if (t !== u.substr(0, t.length)) continue e
                } else {
                    var p = u.toLowerCase().indexOf(i);
                    if (p > -1) l = p; else for (var d = 0; d < t.length; d++) {
                        var v = u.indexOf(i[d], a + 1), m = u.indexOf(r[d], a + 1);
                        c = v >= 0 ? m < 0 || v < m ? v : m : m;
                        if (c < 0) continue e;
                        h = c - a - 1, h > 0 && (a === -1 && (l += 10), l += h, f |= 1 << d), a = c
                    }
                }
                o.matchMask = f, o.exactMatch = l ? 0 : 1, o.$score = (o.score || 0) - l, n.push(o)
            }
            return n
        }, e
    }();
    t.Autocomplete = p, t.CompletionProvider = d, t.FilteredList = v
}), define("ace/autocomplete/text_completer", ["require", "exports", "module", "ace/range"], function (e, t, n) {
    function s(e, t) {
        var n = e.getTextRange(r.fromPoints({row: 0, column: 0}, t));
        return n.split(i).length - 1
    }

    function o(e, t) {
        var n = s(e, t), r = e.getValue().split(i), o = Object.create(null), u = r[n];
        return r.forEach(function (e, t) {
            if (!e || e === u) return;
            var i = Math.abs(n - t), s = r.length - i;
            o[e] ? o[e] = Math.max(s, o[e]) : o[e] = s
        }), o
    }

    var r = e("../range").Range, i = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
    t.getCompletions = function (e, t, n, r, i) {
        var s = o(t, n), u = Object.keys(s);
        i(null, u.map(function (e) {
            return {caption: e, value: e, score: s[e], meta: "local"}
        }))
    }
}), define("ace/ext/language_tools", ["require", "exports", "module", "ace/snippets", "ace/autocomplete", "ace/config", "ace/lib/lang", "ace/autocomplete/util", "ace/autocomplete/text_completer", "ace/editor", "ace/config"], function (e, t, n) {
    "use strict";
    var r = e("../snippets").snippetManager, i = e("../autocomplete").Autocomplete, s = e("../config"),
        o = e("../lib/lang"), u = e("../autocomplete/util"), a = e("../autocomplete/text_completer"), f = {
            getCompletions: function (e, t, n, r, i) {
                if (t.$mode.completer) return t.$mode.completer.getCompletions(e, t, n, r, i);
                var s = e.session.getState(n.row), o = t.$mode.getCompletions(s, t, n, r);
                o = o.map(function (e) {
                    return e.completerId = f.id, e
                }), i(null, o)
            }, id: "keywordCompleter"
        }, l = function (e) {
            var t = {};
            return e.replace(/\${(\d+)(:(.*?))?}/g, function (e, n, r, i) {
                return t[n] = i || ""
            }).replace(/\$(\d+?)/g, function (e, n) {
                return t[n]
            })
        }, c = {
            getCompletions: function (e, t, n, i, s) {
                var o = [], u = t.getTokenAt(n.row, n.column);
                u && u.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/) ? o.push("html-tag") : o = r.getActiveScopes(e);
                var a = r.snippetMap, f = [];
                o.forEach(function (e) {
                    var t = a[e] || [];
                    for (var n = t.length; n--;) {
                        var r = t[n], i = r.name || r.tabTrigger;
                        if (!i) continue;
                        f.push({
                            caption: i,
                            snippet: r.content,
                            meta: r.tabTrigger && !r.name ? r.tabTrigger + "\u21e5 " : "snippet",
                            completerId: c.id
                        })
                    }
                }, this), s(null, f)
            }, getDocTooltip: function (e) {
                e.snippet && !e.docHTML && (e.docHTML = ["<b>", o.escapeHTML(e.caption), "</b>", "<hr></hr>", o.escapeHTML(l(e.snippet))].join(""))
            }, id: "snippetCompleter"
        }, h = [c, a, f];
    t.setCompleters = function (e) {
        h.length = 0, e && h.push.apply(h, e)
    }, t.addCompleter = function (e) {
        h.push(e)
    }, t.textCompleter = a, t.keyWordCompleter = f, t.snippetCompleter = c;
    var p = {
        name: "expandSnippet", exec: function (e) {
            return r.expandWithTab(e)
        }, bindKey: "Tab"
    }, d = function (e, t) {
        v(t.session.$mode)
    }, v = function (e) {
        typeof e == "string" && (e = s.$modes[e]);
        if (!e) return;
        r.files || (r.files = {}), m(e.$id, e.snippetFileId), e.modes && e.modes.forEach(v)
    }, m = function (e, t) {
        if (!t || !e || r.files[e]) return;
        r.files[e] = {}, s.loadModule(t, function (t) {
            if (!t) return;
            r.files[e] = t, !t.snippets && t.snippetText && (t.snippets = r.parseSnippetFile(t.snippetText)), r.register(t.snippets || [], t.scope), t.includeScopes && (r.snippetMap[t.scope].includeScopes = t.includeScopes, t.includeScopes.forEach(function (e) {
                v("ace/mode/" + e)
            }))
        })
    }, g = function (e) {
        var t = e.editor, n = t.completer && t.completer.activated;
        if (e.command.name === "backspace") n && !u.getCompletionPrefix(t) && t.completer.detach(); else if (e.command.name === "insertstring") {
            var r = u.getCompletionPrefix(t), s = u.triggerAutocomplete(t);
            if ((r || s) && !n) {
                var o = i.for(t);
                o.autoShown = !0, o.showPopup(t)
            }
        }
    }, y = e("../editor").Editor;
    e("../config").defineOptions(y.prototype, "editor", {
        enableBasicAutocompletion: {
            set: function (e) {
                e ? (this.completers || (this.completers = Array.isArray(e) ? e : h), this.commands.addCommand(i.startCommand)) : this.commands.removeCommand(i.startCommand)
            }, value: !1
        }, enableLiveAutocompletion: {
            set: function (e) {
                e ? (this.completers || (this.completers = Array.isArray(e) ? e : h), this.commands.on("afterExec", g)) : this.commands.removeListener("afterExec", g)
            }, value: !1
        }, enableSnippets: {
            set: function (e) {
                e ? (this.commands.addCommand(p), this.on("changeMode", d), d(null, this)) : (this.commands.removeCommand(p), this.off("changeMode", d))
            }, value: !1
        }
    })
});
(function () {
    window.require(["ace/ext/language_tools"], function (m) {
        if (typeof module == "object" && typeof exports == "object" && module) {
            module.exports = m;
        }
    });
})();
            